package info.batcloud.fanli.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taobao.api.ApiException;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.TbkOrderDetailsGetRequest;
import com.taobao.api.response.TbkOrderDetailsGetResponse;
import info.batcloud.fanli.core.constants.TaobaoClientConstants;
import info.batcloud.fanli.core.domain.TbkRecommendCoupon;
import info.batcloud.fanli.core.domain.utam.AuctionCode;
import info.batcloud.fanli.core.domain.utam.req.TbkOrderFetchRequest;
import info.batcloud.fanli.core.dto.CommissionItemFetchDTO;
import info.batcloud.fanli.core.dto.CommissionOrderAddDTO;
import info.batcloud.fanli.core.entity.TaobaoItemCat;
import info.batcloud.fanli.core.entity.User;
import info.batcloud.fanli.core.enums.CommissionItemStatus;
import info.batcloud.fanli.core.enums.CommissionOrderStatus;
import info.batcloud.fanli.core.enums.EcomPlat;
import info.batcloud.fanli.core.excel.ExcelImporter;
import info.batcloud.fanli.core.helper.CouponHelper;
import info.batcloud.fanli.core.repository.UserRepository;
import info.batcloud.fanli.core.service.*;
import info.batcloud.fanli.core.settings.MyQuanSetting;
import info.batcloud.fanli.core.taobao.union.domain.TkOrder;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.ParseException;
import java.util.*;

@Service
public class TaobaoUnionServiceImpl implements TaobaoUnionService {

    private static final Logger logger = LoggerFactory.getLogger(TaobaoUnionService.class);

    @Inject
    private CommissionOrderService commissionOrderService;

    @Inject
    private CommissionItemService commissionItemService;

    @Value("${taobaoUnion.commissionOrderFetchSleep}")
    private int commissionOrderFetchSleep;

    @Inject
    private TaobaoItemCatService taobaoItemCatService;

    @Inject
    private UserRepository userRepository;

    @Inject
    private SystemSettingService systemSettingService;

    @Inject
    @Qualifier(TaobaoClientConstants.TAOBAO_CLIENT_ITEM_TBK)
    private TaobaoClient taobaoClient;

    @Override
    public AuctionCode createAuctionCode(String pid, Long auctionId) {
        MyQuanSetting settings = systemSettingService.findActiveSetting(MyQuanSetting.class);
        String url = "%s/getitemgyurl?apkey=%s&itemid=%s&pid=%s&tbname=%s&tpwd=1&shorturl=1";
        url = String.format(url, new Object[]{settings.getServerUrl(), settings.getAppKey(), auctionId, pid, settings.getTbName()});
        AuctionCode auctionCode = new AuctionCode();
        try {
            String responseText = IOUtils.toString(new URL(url));
            JSONObject jsonObject = JSON.parseObject(responseText);
            int code = jsonObject.getIntValue("code");
            if (code != 200) {
            } else {
                JSONObject rs = jsonObject.getJSONObject("result");
                JSONObject data = rs.getJSONObject("data");
                auctionCode.setClickUrl(StringUtils.defaultIfBlank(data.getString("click_url"), data.getString("short_url")));
                auctionCode.setShortLinkUrl(data.getString("short_url"));
                auctionCode.setCouponShortLinkUrl(data.getString("short_url"));
                auctionCode.setCouponLink(data.getString("coupon_click_url"));
                auctionCode.setCouponLinkTaoToken(data.getString("tpwd"));
                auctionCode.setTaoToken(data.getString("tpwd"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return auctionCode;
    }

    @Override
    public boolean fetchOrder(TbkOrderFetchRequest param) {
        logger.info("同步淘宝订单");
        Date startTime = param.getStartTime();
        int total = 0;
        Date endTime = param.getEndTime();
        if (endTime == null) {
            endTime = new Date();
        }
        while (true) {
            Date _endTime = DateUtils.addMinutes(startTime, 15);
            param.setStartTime(startTime);
            param.setEndTime(_endTime);
            String positionIndex = null;
            int page = 1;
            while (true) {
                try {
                    Thread.sleep(commissionOrderFetchSleep);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                param.setPositionIndex(positionIndex);
                TbkOrderDetailsGetResponse.OrderPage orderPage = doFetchOrder(param, page);
                if (orderPage.getResults() != null) {
                    int num = orderPage.getResults().size();
                    total += num;
                    logger.info("同步到订单：" + num + "个，总" + total + "个");
                    if (orderPage.getHasNext()) {
                        positionIndex = orderPage.getPositionIndex();
                        page++;
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
            if (_endTime.after(endTime) || _endTime.equals(endTime)) {
                break;
            }
            startTime = _endTime;
        }
//        while (true) {
//            int page = 1;
//            while (true) {
//                TbkOrderDetailsGetResponse.OrderPage orderPage = doFetchOrder(param, page);
//                int num = orderPage.getResults().size();
//                total += num;
//                if (!orderPage.getHasNext()) {
//                    break;
//                }
//                try {
//                    Thread.sleep(commissionOrderFetchSleep);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                page++;
//            }
//            startTime = DateUtils.addSeconds(startTime, 600);
//            if (startTime.after(endTime)
//                    || startTime.equals(endTime)) {
//                break;
//            }
//            try {
//                Thread.sleep(commissionOrderFetchSleep);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
        logger.info("淘宝订单同步完成, 共同步：" + total + "个");
        return true;
    }

    private TbkOrderDetailsGetResponse.OrderPage doFetchOrder(TbkOrderFetchRequest param, int page) {

        TbkOrderDetailsGetRequest req = new TbkOrderDetailsGetRequest();
        req.setStartTime(DateFormatUtils.format(param.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
        req.setEndTime(DateFormatUtils.format(param.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
        req.setPageNo(Long.valueOf(page));
        req.setPageSize(20L);
        if (param.getPayStatus() != null) {
            req.setTkStatus(Long.valueOf(param.getPayStatus().value));
        }
        if (param.getQueryType() != null) {
            req.setQueryType(param.getQueryType().value);
        }
        if (param.getScene() != null) {
            req.setOrderScene(Long.valueOf(param.getScene().value));
        } else {
            req.setOrderScene(1L);
        }

        TbkOrderDetailsGetResponse rsp = null;
        List<CommissionOrderAddDTO> coList = new ArrayList<>();
        try {
            rsp = taobaoClient.execute(req);//没给data赋值
            TbkOrderDetailsGetResponse.OrderPage orderPage = rsp.getData();
            /*if (orderPage==null){
                logger.info("没有查询到订单，" + req.getStartTime() + " - " + req.getEndTime());
                return orderPage;
            }*/
            List<TbkOrderDetailsGetResponse.PublisherOrderDto> orderList = rsp.getData().getResults();//null异常
            if (orderList == null) {
                logger.info("没有查询到订单，" + req.getStartTime() + " - " + req.getEndTime());
                return orderPage;
            }
            for (TbkOrderDetailsGetResponse.PublisherOrderDto order : orderList) {
                User user = null;
                if (order.getSpecialId() != null) {
                    user = userRepository.findByTaobaoSpecialId(order.getSpecialId().toString());
                } else if (order.getRelationId() != null) {
                    user = userRepository.findByTaobaoRelationId(order.getRelationId().toString());
                }
                CommissionOrderAddDTO co = new CommissionOrderAddDTO();
                if (user != null) {
                    co.setUserId(user.getId());
                }
                co.setItemId(order.getItemId().toString());
                co.setItemNum(order.getItemNum().intValue());
                /**
                 * 佣金比例是 收入比例*分成比例, 预估佣金比例
                 * */
                co.setEstimateCommissionRate(Float.valueOf(order.getTotalCommissionRate()) * 100); //存的是百分比
                /**
                 * 佣金预估,如果预估收入不为0，那么佣金预估为预估收入，否则为效果预估
                 * */
                float commission = Float.valueOf(order.getTotalCommissionFee() == null ? "0" : order.getTotalCommissionFee());
                co.setEstimateCommissionFee(commission > 0 ? commission : Float.valueOf(order.getPubSharePreFee() == null ? "0" : order.getPubSharePreFee()));
                /**
                 * 佣金比例，真实结算以后才会有
                 * */
                co.setCommissionRate(Float.valueOf(toValue(order.getTotalCommissionRate())));
                co.setCommissionFee(Float.valueOf(toValue(order.getTotalCommissionFee())));
                co.setItemTitle(order.getItemTitle());
                try {
                    co.setCreateTime(DateUtils.parseDate(order.getTkCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                co.setEcomPlat(determineEcomPlat(order.getOrderType()));
                co.setOrderNo(order.getTradeParentId() != null ? order.getTradeParentId() : order.getTradeId());
                co.setPayFee(Float.valueOf(toValue(order.getAlipayTotalPrice())));
                co.setPrice(Float.valueOf(order.getItemPrice()));
                co.setShopTitle(order.getSellerNick());
                if (order.getTkEarningTime() != null) {
                    try {
                        co.setPlatSettledTime(DateUtils.parseDate(order.getTkEarningTime(), "yyyy-MM-dd HH:mm:ss"));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                co.setStatus(determineCommissionOrderStatusValue(order.getTkStatus().intValue()));
                coList.add(co);
            }
            Collections.reverse(coList);
            commissionOrderService.saveCommissionOrderList(coList);
            return orderPage;
        } catch (ApiException e) {
            e.printStackTrace();
        }

        return null;
    }

    private String toValue(String valStr) {
        if (valStr == null) {
            return "0";
        }
        return valStr;
    }

    @Override
    public ImportOrderResult importOrder(InputStream inputStream) {
        ImportOrderResult result = new ImportOrderResult();
        try {
            List<TkOrder> orderList = ExcelImporter.execute(inputStream, TkOrder.class, true);
            List<CommissionOrderAddDTO> coList = new ArrayList<>();
            for (TkOrder tkOrder : orderList) {
                /**
                 * 非代理用户所用的pid为其邀请者的pid，
                 * 代理用户的所用的pid为其自身的pid，
                 * 所以代理的所有的订单都需要分佣给其自身
                 * */
                User user = null;
                if (StringUtils.isNotBlank(tkOrder.getSpecialId())) {
                    user = userRepository.findByTaobaoSpecialId(tkOrder.getSpecialId());
                } else if (StringUtils.isNotBlank(tkOrder.getRelationId())) {
                    user = userRepository.findByTaobaoRelationId(tkOrder.getRelationId());
                }
                CommissionOrderAddDTO co = new CommissionOrderAddDTO();
                if (user != null) {
                    co.setUserId(user.getId());
                }
                co.setItemId(tkOrder.getItemId());
                co.setItemNum(tkOrder.getItemNum());
                /**
                 * 佣金比例是 收入比例*分成比例, 预估佣金比例
                 * */
                co.setEstimateCommissionRate(toFloatValue(tkOrder.getShareRate()) * toFloatValue(tkOrder.getIncomeRate()) / 100);
                /**
                 * 佣金预估,如果预估收入不为0，那么佣金预估为预估收入，否则为效果预估
                 * */
                co.setEstimateCommissionFee(tkOrder.getEstimateIncome() > 0 ? tkOrder.getEstimateIncome() : tkOrder.getEstimateFee());
                /**
                 * 佣金比例，真实结算以后才会有
                 * */
                co.setCommissionRate(toFloatValue(tkOrder.getCommissionRate()));
                /**
                 * 结算佣金是 结算佣金*分佣比例
                 * */
                String shareRateStr = tkOrder.getShareRate().replace("%", "");
                float shareRate = Float.valueOf(shareRateStr);
                co.setCommissionFee(tkOrder.getCommissionFee() * shareRate / 100);
                co.setItemTitle(tkOrder.getItemTitle());
                co.setCreateTime(tkOrder.getCreateTime());
                co.setEcomPlat(determineEcomPlat(tkOrder.getType()));
                co.setOrderNo(tkOrder.getOrderNo());
                co.setPayFee(tkOrder.getPayFee());
                co.setPlatSettledTime(tkOrder.getSettledTime());
                co.setPrice(tkOrder.getPrice());
                co.setShopTitle(tkOrder.getShopTitle());
                co.setStatus(determineCommissionOrderStatus(tkOrder.getStatus()));
                coList.add(co);
            }
            Collections.reverse(coList);
            commissionOrderService.saveCommissionOrderList(coList);
            result.setTotalNum(coList.size());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Override
    public boolean importRecommendCoupon(InputStream is) {
        try {
            List<TbkRecommendCoupon> tbkRecommendCouponList = ExcelImporter.execute(is, TbkRecommendCoupon.class, true);
            List<CommissionItemFetchDTO> dtoList = new ArrayList<>();
            for (TbkRecommendCoupon co : tbkRecommendCouponList) {
                CommissionItemFetchDTO dto = new CommissionItemFetchDTO();
                Date now = new Date();
                dto.setListTime(now);
                /**
                 * 商品的下架时间为当前的日期+7天，优惠券的下架时间，活动的下架时间取最大者
                 * */
                Date delistTime = DateUtils.addDays(now, 7);
                dto.setCouponStartTime(co.getCouponStartTime());
                dto.setCouponEndTime(co.getCouponEndTime());
                dto.setDelistTime(Collections.max(Arrays.asList(delistTime, co.getCouponEndTime())));
                TaobaoItemCat taobaoItemCat = taobaoItemCatService.findByName(co.getItemCatName(), 0);
                if (taobaoItemCat != null) {
                    dto.setSourceCatId(taobaoItemCat.getCid());
                }
                dto.setShopTitle(co.getSellerName());
                dto.setCouponRemainCount(co.getCouponRemainCount());
                dto.setCouponTotalCount(co.getCouponTotalCount());
                dto.setCoupon(true);
                dto.setSummary(co.getCouponInfo());
                dto.setCouponInfo(co.getCouponInfo());
                float[] couponInfos = CouponHelper.parseCouponAmount(co.getCouponInfo());
                dto.setCouponValue(couponInfos[1]);
                dto.setSourceItemUrl(co.getItemUrl());
                dto.setSourceItemId(co.getItemId());
                dto.setTitle(co.getTitle());
                dto.setSourceItemClickUrl(co.getClickUrl());
                dto.setCouponClickUrl(co.getCouponClickUrl());
                dto.setOriginPrice(co.getPrice());
                dto.setCouponThresholdAmount(couponInfos[0]);
                dto.setCommissionRate(co.getCommissionRate());
                dto.setEcomPlat(co.getPlatform().trim().equals("淘宝") ? EcomPlat.TAOBAO : EcomPlat.TMALL);
                dto.setImgList(Arrays.asList(co.getPicUrl()));
                dto.setPicUrl(co.getPicUrl());
                dto.setSales(co.getSales());
                dto.setStatus(CommissionItemStatus.ONSALE);
                dto.setItemPlace(null);
                dto.setRecommend(true);
                dtoList.add(dto);
                if (dtoList.size() >= 100) {
                    commissionItemService.saveCommissionItemListSync(dtoList);
                    dtoList = new ArrayList<>();
                }
            }
            commissionItemService.saveCommissionItemListSync(dtoList);
            logger.info("每日优惠券导入成功", true);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private static Float toFloatValue(String val) {
        return Float.valueOf(val.replace("%", ""));
    }

    private static EcomPlat determineEcomPlat(String type) {
        switch (type.trim()) {
            case "天猫":
                return EcomPlat.TMALL;
            case "淘宝":
                return EcomPlat.TAOBAO;
            default:
                return EcomPlat.TAOBAO;
        }
    }

    private static CommissionOrderStatus determineCommissionOrderStatus(String status) {
        switch (status.trim()) {
            case "订单成功":
            case "订单付款":
                return CommissionOrderStatus.PAID;
            case "订单结算":
                return CommissionOrderStatus.WAIT_SETTLE;
            case "订单失效":
            default:
                return CommissionOrderStatus.INVALID;
        }
    }

    private static CommissionOrderStatus determineCommissionOrderStatusValue(int status) {
        switch (status) {
            case 12:
            case 14:
                return CommissionOrderStatus.PAID;
            case 3:
                return CommissionOrderStatus.WAIT_SETTLE;
            case 13:
            default:
                return CommissionOrderStatus.INVALID;
        }
    }


}
